/*************************************************************
 * File: HibernateEvictCacheInterceptor.java
 * Copyright (c) 2012
 * Author: Huang Shaobin
 * Email: Shaobin.Software@gmail.com Shaobin_Software@163.com 
 * Date: Feb 11, 2013
 * Description: 
 ************************************************************/

package snow.core.persistence.hibernate;

import java.lang.reflect.Method;
import java.util.List;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;

import snow.core.persistence.Entity;

/**
 * 清除Hibernate二级缓存的拦截器
 * 
 * @author Shaobin.Software@gmail.com Shaobin_Software@163.com
 * @version 1.0
 */
public class HibernateEvictCacheInterceptor implements MethodInterceptor, InitializingBean {

	private List<String> evictMethods;
	private TaskExecutor taskExecutor;
	private HibernateEvictCacheHandler hibernateEvictCacheHandler;

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(taskExecutor, "The property [taskExecutor] must not be null!");
		Assert.notNull(hibernateEvictCacheHandler, "The property [hibernateEvictCacheHandler] must not be null!");
	}

	public List<String> getEvictMethods() {
		return evictMethods;
	}

	public HibernateEvictCacheHandler getHibernateEvictCacheHandler() {
		return this.hibernateEvictCacheHandler;
	}

	public TaskExecutor getTaskExecutor() {
		return taskExecutor;
	}

	public Object invoke(MethodInvocation invocation) throws Throwable {
		final Object result = invocation.proceed(); // 自行方法
		if (CollectionUtils.isNotEmpty(evictMethods)) {
			final Method method = invocation.getMethod(); // 目标方法
			final Object[] args = invocation.getArguments(); // 目标参数
			final String methodName = method.getName();
			for (String evictMethod : evictMethods) {
				if (!PatternMatchUtils.simpleMatch(evictMethod, methodName)) {
					continue;
				}
				if (!ArrayUtils.isEmpty(args)) {
					final Object argument = args[0];
					if (argument instanceof Entity) {
						final Entity<?> entity = (Entity<?>) argument;
						taskExecutor.execute(new Runnable() {

							public void run() {
								hibernateEvictCacheHandler.evictEntity(entity.getClass(), entity.getId());
							}
						});
					}
				}
			}
		}
		return result;
	}

	public void setEvictMethods(List<String> evictMethods) {
		this.evictMethods = evictMethods;
	}

	public void setHibernateEvictCacheHandler(HibernateEvictCacheHandler hibernateEvictCacheHandler) {
		this.hibernateEvictCacheHandler = hibernateEvictCacheHandler;
	}

	public void setTaskExecutor(TaskExecutor taskExecutor) {
		this.taskExecutor = taskExecutor;
	}

}
